﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;
using Microsoft.Win32;

namespace FetionLite
{
    public partial class LoginForm : Form
    {
        delegate void CloseFormDelegate();
        delegate void SetStatusTextDelegate(string statusText);

        private System.Threading.Timer _autoLoginTimer;

        public LoginForm()
        {
            InitializeComponent();
        }

        public bool LoginSuccessed { get; set; }

        private void miLogin_Click(object sender, EventArgs e)
        {
            PerformLogin();
        }

        private delegate void PerformLoginDelegate();
        private void PerformLogin()
        {
            string mobile = this.txtMobile.Text.Trim();
            string pwd = this.txtPwd.Text.Trim();

            FetionLiteSettings.Instance.SaveAuth = this.chkSaveAuth.Checked;
            FetionLiteSettings.Instance.AutoLogin = this.chkAutoLogin.Checked;
            FetionLiteSettings.Instance.Mobile = mobile;
            FetionLiteSettings.Instance.Password = pwd;

            //setup libfetion callback
            Fetion.Instance.OnLoginStateChanged += new Fetion.LoginStateChangedDelegate(OnLoginStateChanged);

            if (FetionLiteSettings.Instance.ServerAddress.Length > 0)
                if (!Fetion.Instance.SetServerAddress(FetionLiteSettings.Instance.ServerAddress))
                    FetionLiteSettings.Instance.ServerAddress = "";

            Fetion.Instance.Login(mobile, pwd);
        }

        private void miExit_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Abort;
            this.Close();
        }

        void OnLoginStateChanged(LoginState loginState)
        {
            switch (loginState)
            {
                case LoginState.FX_LOGIN_CONNECTING:
                    SetStatus("正在连接服务器");
                    break;
                case LoginState.FX_LOGIN_WAIT_AUTH:
                    SetStatus("等待认证");
                    break;
                case LoginState.FX_LOGIN_AUTH_OK:
                    SetStatus("认证成功");
                    break;
                case LoginState.FX_LOGIN_GCL_GETTING:
                    SetStatus("正在获取联系人列表");
                    break;
                case LoginState.FX_LOGIN_GCL_OK:
                    SetStatus("获取联系人列表成功");
                    break;

                case LoginState.FX_LOGIN_GP_GETTING:
                    SetStatus("正在获取联系人状态");
                    break;
                case LoginState.FX_LOGIN_GP_OK:
                    SetStatus("获取联系人状态成功");
                    break;
                case LoginState.FX_LOGIN_GSML_OK:
                    SetStatus("获取定时短信列表成功");
                    break;
                case LoginState.FX_LOGIN_NETWORK_ERROR:
                    SetStatus("网络错误");
                    break;
                case LoginState.FX_LOGIN_UNKOWN_ERROR:
                    SetStatus("未知错误");
                    break;
                case LoginState.FX_LOGIN_UNKOWN_USR:
                    SetStatus("用户不存在");
                    break;
                case LoginState.FX_LOGIN_GCL_FAIL:
                    SetStatus("获取联系人列表失败");
                    break;
                case LoginState.FX_LOGIN_GP_FAIL:
                    SetStatus("获取联系人状态失败");
                    break;
                case LoginState.FX_LOGIN_GSML_FAIL:
                    SetStatus("获取定时短信列表失败");
                    break;
                case LoginState.FX_LOGIN_TIMEOUT:
                    SetStatus("登陆超时?");
                    break;
                case LoginState.FX_LOGIN_URI_ERROR:
                    SetStatus("get the user's uri fail");
                    break;
                case LoginState.FX_LOGIN_SERVER_ERROR:
                    SetStatus("error fetion server");
                    break;
                case LoginState.FX_LOGIN_SERVER_REFUSE:
                    SetStatus("服务器拒绝");
                    break;
                case LoginState.FX_LOGIN_FAIL:
                    SetStatus("登陆失败");
                    break;
                case LoginState.FX_LOGIN_OK:
                    SetStatus("登录成功");

                    //登陆成功后保存用户名密码及服务器地址
                    if (!FetionLiteSettings.Instance.SaveAuth)
                    {
                        FetionLiteSettings.Instance.Mobile = "";
                        FetionLiteSettings.Instance.Password = "";
                    }

                    if (FetionLiteSettings.Instance.ServerAddress.Length == 0)
                        FetionLiteSettings.Instance.ServerAddress = Fetion.Instance.GetServerAddress();

                    FetionLiteSettings.Instance.Persist();

                    this.LoginSuccessed = true;
                    CloseThis();

                    break;
            }
        }

        //void Instance_OnNewMessage(int fromId)
        //{
        //    MessageBox.Show(fromId.ToString());
        //}

        private void LoginForm_Load(object sender, EventArgs e)
        {
            this.chkSaveAuth.Checked = FetionLiteSettings.Instance.SaveAuth;
            this.chkAutoLogin.Checked = FetionLiteSettings.Instance.AutoLogin;

            if (FetionLiteSettings.Instance.SaveAuth)
            {                
                this.txtMobile.Text = FetionLiteSettings.Instance.Mobile;
                this.txtPwd.Text = FetionLiteSettings.Instance.Password;
            }

            //启动计时器，1秒钟后进行自动登录
            if (FetionLiteSettings.Instance.AutoLogin)
            {
                _autoLoginTimer = new System.Threading.Timer(new TimerCallback(OnTimer), null, 1000, Timeout.Infinite);
            }
        }

        private void OnTimer(object state)
        {
            _autoLoginTimer.Dispose();

            this.BeginInvoke(new PerformLoginDelegate(PerformLogin));
        }

        private void fetion_LoginFailed(object sender, EventArgs e)
        {
            this.miLogin.Enabled = true;
            this.miExit.Enabled = true;
        }

        private void fetion_Load(object sender, EventArgs e)
        {
            CloseFormDelegate CloseForm = new CloseFormDelegate(CloseThis);
            this.Invoke(CloseForm);
        }

        private void SetStatus(string statusText)
        {
            SetStatusTextDelegate setStatusText = SetStatusText;

            if (this.InvokeRequired)
            {
                this.BeginInvoke(setStatusText, statusText);
            }
            else
            {
                setStatusText(statusText);
            }
        }

        private void CloseThis()
        {
            CloseFormDelegate closeForm = CloseForm;

            if (this.InvokeRequired)
            {                
                this.Invoke(closeForm);
            }
            else
            {
                closeForm();
            }
        }

        private void SetStatusText(string statusText)
        {
            this.lblStatus.Text = statusText;
        }

        private void CloseForm()
        {
            this.DialogResult = DialogResult.OK;
            this.Close();
        }
    }
}